#include "unp.h"

static void recvfrom_alarm(int);

int main(int argc, char** argv)
{
  if (argc < 2)
  {
    printf("usage: cli_daytime <host>\n");
    exit(-1);
  }
  
  
  char buff[128] = {'\0'};
  char addr_buff[128] = {'\0'};
  int n;
  fd_set rset;
  sigset_t sigset_alrm, sigset_empty;
 
  struct sockaddr_in sevraddr;
  struct sockaddr_in *reply_addr = (struct sockaddr_in*)malloc(sizeof(sevraddr));
  int sockfd = socket(AF_INET,SOCK_DGRAM,0);
  
  memset(&sevraddr,0,sizeof(sevraddr));
  
  sevraddr.sin_family = AF_INET;
  inet_pton(AF_INET,argv[1],&sevraddr.sin_addr);
  sevraddr.sin_port = htons(10086);  

  const int on = 1; 
  setsockopt(sockfd,SOL_SOCKET,SO_BROADCAST,&on,sizeof(on));

  FD_ZERO(&rset);
  sigemptyset(&sigset_empty);
  sigemptyset(&sigset_alrm);
  sigaddset(&sigset_alrm,SIGALRM);

  signal(SIGALRM,recvfrom_alarm);
  
  while(fgets(buff,sizeof(buff),stdin) != NULL)
  {
    memset(buff,0,sizeof(buff));
    int ret = sendto(sockfd,"",1,0,(struct sockaddr*)(&sevraddr),sizeof(sevraddr));  
    sigprocmask(SIG_BLOCK,&sigset_alrm,NULL);
    alarm(1);  

    if (ret < 0)
    {
      printf("send error:%s\n",strerror(errno));
      exit(-1);
    }

    for(;;)
    {
      socklen_t len = sizeof(sevraddr);
      FD_SET(sockfd,&rset);
      n = pselect(sockfd+1,&rset,NULL,NULL,NULL,&sigset_empty);
      if ( n < 0 && errno == EINTR) break;

      n = recvfrom(sockfd,buff,sizeof(buff),0,(struct sockaddr*)reply_addr,&len);
      if ( n < 0 && errno == EINTR) {
        printf("n < 0\n");
        break;
      } else {
        buff[n] = '\0';
        printf("from %s:%s\n",inet_ntop(AF_INET,&reply_addr->sin_addr,addr_buff,sizeof(addr_buff)),buff);
      }
    }
  }
  
  free(reply_addr);   
  shutdown(sockfd,SHUT_WR);
  close(sockfd);
  return 0;
}

static void recvfrom_alarm(int signo)
{

  return;
}
